# -*- coding: utf-8 -*-
# created on 2016/12/06

from sympy import expand, apart, solveset
from mathsolver.functions.base import *
from mathsolver.functions.shulie.Fundamental import *
from mathsolver.functions.shulie.Distinguish import *
from sympy.abc import n
from mathsolver.functions.mathematica.mathematicaSolve import MathematicaSimplify


class GetSums001(BaseFunction):
    """
    求等差数列: an = a*n+b(a可以为0) 的n项和
    """
    def solver(self, *args):
        an = args[0]
        f_num = args[1]
        l_num = args[2]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        assert sl_linear_n(eq_right, symbol)
        a1 = eq_right.subs({symbol: 1})
        a, b = sl_linear_poly_coeffs(eq_right, symbol)
        sn = (a1 + (f_num - 1) * a + a1 + (l_num - 1) * a) * (l_num - f_num + 1) / 2
        sn = expand(sn)
        sn = simplify(sn)
        if f_num == 1:
            self.steps.append(["", "由等差数列的求和公式，知"])
            self.steps.append(["", "%s的前%s项和为%s" % (new_latex(eq_right), new_latex(l_num), new_latex(sn))])
        self.output.append(BaseValues([sn]))
        return self


class GetSums002(BaseFunction):
    """
    求等比数列: an = c*q**(a*n+b) 的n项和
    """
    def solver(self, *args):
        an = args[0]
        f_num = args[1]
        l_num = args[2]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        assert sl_exp_poly(eq_right, symbol)
        a1 = eq_right.subs({symbol: 1})
        a2 = eq_right.subs({symbol: 2})
        q = simplify(a2 / a1)
        steps = [["", "由等比数列求和公式，知"]]
        if q == 1:
            sn = (l_num - f_num + 1) * a1
            sn = simplify(sn)
            if f_num == 1:
                steps.append(["", "%s的前%s项和为：%s"
                              % (new_latex(shulie_name(min_index)), new_latex(l_num), new_latex(sn))])
            self.output.append(sn)
        else:
            sn = a1 * q ** (f_num - 1) * (1 - q ** (l_num - f_num + 1)) / (1 - q)
            sn = expand(sn)
            sn = simplify(sn)
            if f_num == 1:
                steps.append(["", "%s的前%s项和为：%s" % (new_latex(eq_right), new_latex(l_num), new_latex(sn))])
            self.output.append(BaseValues([sn]))
        self.steps.extend(steps)
        return self


class GetSums003(BaseFunction):
    """
    错位相减法：求 an = 等差*等比 型数列的n项和
    """
    def solver(self, *args):
        an = args[0]
        l_num = args[2]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        assert sl_dengcha_bi_poly(eq_right, symbol)
        an_dc, bn_db = sl_dengcha_bi_parts(eq_right)
        an_1 = an_dc.subs({symbol: 1})
        bn_1 = bn_db.subs({symbol: 1})
        an_d = an_dc.subs({symbol: 2}) - an_1
        an_d = simplify(an_d)
        bn_q = bn_db.subs({symbol: 2}) / bn_1
        bn_q = simplify(bn_q)
        self.steps.append(["", "由错位相减法，得"])
        if bn_q.free_symbols:
            self.steps.append(["", "当%s = 1时" % (new_latex(bn_q))])
            sn1 = l_num * an_1 + (l_num - 1) * l_num * an_d / 2
            sn1 = simplify(sn1)
            self.steps.append(["", "%s的前%s项和为%s" % (new_latex(an[0]), new_latex(l_num), new_latex(sn1))])
            self.steps.append(["", "当%s %s 1时" % (new_latex(bn_q), new_latex("\\ne"))])
            c1 = bn_db.subs({symbol: 2})
            p1 = c1 * (1 - bn_q ** (l_num - 1)) / (1 - bn_q)
            bn_n1 = bn_db.subs({symbol: l_num + 1})
            an_n = an_dc.subs({symbol: l_num})
            sn2 = (an_1 * bn_1 + an_d * p1 - an_n * bn_n1) / (1 - bn_q)
            sn2 = simplify(sn2)
            self.steps.append(["", "%s的前%s项和为%s" % (new_latex(an[0]), new_latex(l_num), new_latex(sn2))])
            new_sn = BasePieceShuLie({"var": symbol, "name": an[0],
                                      "expression": [[sn1, range(1, 2)], [sn2, range(2, 100000)]]})
            self.output.append(new_sn)
        else:
            c1 = bn_db.subs({symbol: 2})
            p1 = c1 * (1 - bn_q ** (l_num - 1)) / (1 - bn_q)
            bn_n1 = bn_db.subs({symbol: l_num + 1})
            an_n = an_dc.subs({symbol: l_num})
            sn = (an_1 * bn_1 + an_d * p1 - an_n * bn_n1) / (1 - bn_q)
            sn = simplify(sn)
            self.steps.append(["", "%s的前%s项和为%s" % (new_latex(an[0]), new_latex(l_num), new_latex(sn))])
            self.output.append(BaseValues([sn]))
        self.label.add("错位相减法求数列和")
        return self


class GetSums004(BaseFunction):
    """
    裂项求和, 通过apart展开
    """
    def solver(self, *args):
        an = args[0]
        f_num = args[1]
        l_num = args[2]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        eq_right = apart(eq_right)
        flag, minus_left, minus_right, step = leijia_parts(eq_right, symbol)
        assert flag
        steps = [["", "裂项,得"],
                 ["", "%s = %s %s" % (new_latex(sympify(xiangs[0])), new_latex(minus_left), new_latex(minus_right))]]
        minus_left_1 = minus_left.subs({symbol: f_num})
        minus_right_1 = minus_right.subs({symbol: f_num})
        if (not minus_left_1.is_infinite) and (not minus_right_1.is_infinite):
            minus_left_nstep = minus_left.subs({symbol: symbol + step})
            if minus_left_nstep + minus_right == 0:  # a_{n} = f(n)-f(n+1)
                left_part = 0
                right_part = 0
                for i in range(f_num, step + f_num):
                    left_part += minus_left.subs({symbol: i})
                for i in range(1, step + 1):
                    right_part += minus_right.subs({symbol: l_num + 1 - i})
                sn = left_part + right_part
                steps.append(
                    ["", "∴ %s + %s + %s + %s = %s %s + %s %s + %s + %s %s = %s" % (new_latex(shulie_name[0](1)),
                                                                                    new_latex(shulie_name[0](2)),
                                                                                    "\\cdots",
                                                                                    new_latex(
                                                                                        shulie_name[0](l_num)),
                                                                                    new_latex(minus_left.subs(
                                                                                        {symbol: 1})),
                                                                                    new_latex(minus_right.subs(
                                                                                        {symbol: 1})),
                                                                                    new_latex(minus_left.subs(
                                                                                        {symbol: 2})),
                                                                                    new_latex(minus_right.subs(
                                                                                        {symbol: 2})),
                                                                                    "\\cdots",
                                                                                    new_latex(minus_left.subs(
                                                                                        {symbol: l_num})),
                                                                                    new_latex(minus_right.subs(
                                                                                        {symbol: l_num})),
                                                                                    new_latex(sn))])
                if f_num == 1:
                    steps.append(
                        ["", "∴ %s的前%s项和为: %s" % (new_latex(sympify(xiangs[0])), new_latex(l_num), new_latex(sn))])
            else:  # a_{n} = f(n+1)-f(n)
                left_part = 0
                right_part = 0
                for i in range(f_num, step + f_num):
                    left_part = minus_left.subs({symbol: l_num + 1 - i})
                    right_part = minus_right.subs({symbol: i})
                sn = left_part + right_part
                steps.append(
                    ["", "%s + %s + %s + %s = %s - %s + %s - %s + %s - %s = %s" % (new_latex(shulie_name[0](1)),
                                                                                   new_latex(shulie_name[0](2)),
                                                                                   "\\cdots",
                                                                                   new_latex(
                                                                                       shulie_name[0](l_num)),
                                                                                   new_latex(minus_left.subs(
                                                                                       {symbol: 1})),
                                                                                   new_latex(minus_right.subs(
                                                                                       {symbol: 1})),
                                                                                   new_latex(minus_left.subs(
                                                                                       {symbol: 2})),
                                                                                   new_latex(minus_right.subs(
                                                                                       {symbol: 2})),
                                                                                   new_latex(minus_left.subs(
                                                                                       {symbol: l_num})),
                                                                                   new_latex(minus_right.subs(
                                                                                       {symbol: l_num})),
                                                                                   new_latex(sn))])
                if f_num == 1:
                    steps.append(
                        ["", "∴ %s的前%s项和为: %s" % (new_latex(sympify(xiangs[0])), new_latex(l_num), new_latex(sn))])
            self.output.append(BaseNumbers([sn]))
        self.steps.extend(steps)
        return self


class GetSums005(BaseFunction):
    """
    求 an = n**p 的前n项和
    """
    def solver(self, *args):
        an = args[0]
        num = args[1]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        assert sl_np_poly(eq_right, symbol)
        exp = eq_right.args[1]
        if exp == 2:
            sn = num * (num + 1) * (2 * num + 1) / 6
        elif exp == 3:
            sn = num ** 2 * (num + 1) ** 2 / 4
        elif exp == 4:
            sn = num * (num + 1) * (2 * num + 1) * (3 * num ** 2 + 3 * num - 1) / 30
        elif exp == 5:
            sn = num ** 2 * (num + 1) ** 2 * (2 * num ** 2 + 2 * num - 1) / 12
        elif exp == 6:
            sn = num * (num + 1) * (2 * num + 1) * (3 * num ** 4 + 6 * num ** 3 - 3 * num + 1) / 42
        elif exp == 7:
            sn = num ** 2 * (num + 1) ** 2 * (3 * num ** 4 + 6 * num ** 3 - num ** 2 - 4 * num + 2) / 24
        else:
            raise Exception('Try Error!')
        self.output.append(BaseValues([sn]))
        self.label.add("求n^p的前n项和")
        return self


class GetSums006(BaseFunction):
    def solver(self, *args):
        """
        裂项求和：根式类型 an = 1/(sqrt(a(n) + sqrt(a(n+1))
        """
        an = args[0]
        num = args[1]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        judge, parts = sl_liexiang002(eq_right, symbol)
        assert judge
        max_an = parts[0]
        min_an = parts[1]
        new_an = min_an
        new_a1 = new_an.subs({symbol: 1})
        new_d = new_an.subs({symbol: 2}) - new_a1
        first_index = (min_an - new_a1) / new_d + 1
        last_index = (max_an - new_a1) / new_d + 1
        jianju = last_index - first_index
        part1 = 0
        part2 = 0
        for i in range(1, jianju + 1):
            part1 += sqrt(new_an.subs({symbol: i}))
            part2 += sqrt(new_an.subs({symbol: num + i}))
        sn = simplify(part2 - part1)
        self.output.append(BaseValues([sn]))
        return self


class GetSums007(BaseFunction):
    """
    裂项求和：根式类型 an = 1/(sqrt(a(n)) - 1 / sqrt(a(n+1))
    通过MathematicaSimplify展开
    """
    def solver(self, *args):
        an = args[0]
        num = args[1]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        if len(str(eq_right)) > 15:
            eq_right = MathematicaSimplify().solver(BasePoly(eq_right)).output[0].sympify()
        flag, minus_left, minus_right, step = leijia_parts(eq_right, symbol)
        assert flag
        self.steps.append(["", "裂项,得"])
        self.steps.append(["", "%s = %s %s"
                           % (new_latex(sympify(xiangs[0])), new_latex(minus_left), new_latex(minus_right))])
        minus_left_1 = minus_left.subs({symbol: 1})
        minus_right_1 = minus_right.subs({symbol: 1})
        if (not minus_left_1.is_infinite) and (not minus_right_1.is_infinite):
            minus_left_nstep = minus_left.subs({symbol: symbol + step})
            if minus_left_nstep + minus_right == 0:
                left_part = 0
                right_part = 0
                for i in range(1, step + 1):
                    left_part += minus_left.subs({symbol: i})
                    right_part += minus_right.subs({symbol: num + i - 1})
            else:
                left_part = 0
                right_part = 0
                for i in range(1, step + 1):
                    right_part += minus_left.subs({symbol: i})
                    left_part += minus_right.subs({symbol: num + i - 1})
            sn = left_part + right_part
            self.output.append(BaseNumbers([sn]))
        self.steps.append(["", "由裂项求和法, 得"])
        self.steps.append(["", "%s的前%s项和为: %s" % (new_latex(sympify(xiangs[0])), new_latex(num), new_latex(sn))])
        self.label.add("裂项求和法求数列和")
        return self


class GetSums008(BaseFunction):
    """
    求绝对值的和: 如 an = c*|an+b|
    """
    def solver(self, *args):
        an = args[0]
        num = args[1]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        if len(xiangs) != 1:
            raise Exception('Try Error!')
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        judge, coeff, bn = sl_abs_linear_n(eq_right, symbol)
        assert judge
        jies = solveset(bn >= 0, symbol, S.Reals)
        l, r, lopen, ropen = jies.args
        if r.is_infinite:
            if l < 1:
                tn = GetSums001().solver(BaseEq([shulie_name[0](min_index), bn]).sympify(),
                                         BaseNumber(num).sympify())
                sn = simplify(coeff * tn)
                return sn
            else:
                if l.is_integer:
                    fu_first = 1
                    fu_final = l - 1
                else:
                    fu_first = 1
                    fu_final = int(l)
                if fu_first > fu_final:
                    tn = GetSums001().solver(BaseEq([shulie_name[0](min_index), bn]).sympify(),
                                             BaseNumber(num).sympify())
                    sn = simplify(coeff * tn)
                    return sn
                else:
                    stepsolver1 = GetSums001().solver(BaseEq([shulie_name[0](min_index), bn]).sympify(),
                                                      BaseNumber(num).sympify())
                    tn1 = stepsolver1.output[0].sympify()
                    tn1 = tn1[0]
                    sn1 = simplify(-coeff * tn1)
                    stepsolver2 = GetSums001().solver(BaseEq([shulie_name[0](min_index), bn]).sympify(),
                                                      BaseNumber(fu_final).sympify())
                    tn2 = stepsolver2.output[0].sympify()
                    tn2 = tn2[0]
                    stepsolver3 = GetSums001().solver(BaseEq([shulie_name[0](min_index), bn]).sympify(),
                                                      BaseNumber(num).sympify())
                    tn3 = stepsolver3.output[0].sympify()
                    tn3 = tn3[0]
                    sn2 = -2 * coeff * tn2 + coeff * tn3
                    self.steps.append(
                        ["", "设 %s 的前 %s 项和为 %s" % (new_latex(an[0]), new_latex(symbol), sympify("T_(n)"))])
                    tongxiang = BasePieceShuLie({"var": sympify("T_(n)"),
                                                 "expression": [{"main": sn1, "equality": [], "belong": [],
                                                                 "inequality": [[symbol, "<=", fu_final]]},
                                                                {"main": sn2, "equality": [], "belong": [],
                                                                 "inequality": [[symbol, ">", fu_final]]}],
                                                 "type": "",
                                                 "name": sympify("T_(n)")})
                    self.steps.append(["", "∴ %s" % (tongxiang.printing())])
                    self.output.append(tongxiang)
                    self.label.add("求绝对值数列的和")
                    return self


class GetSums010(BaseFunction):
    """
    分组求和法
    """
    def solver(self, *args):
        an = args[0]
        f_num = args[1]
        l_num = args[2]
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        eq_right = MathematicaSimplify().solver(BasePoly(eq_right)).output[0].sympify()
        # eq_right = eq_right.expand()
        assert eq_right.is_Add
        cls = [GetSums001, GetSums002, GetSums003, GetSums004, GetSums005, GetSums006, GetSums007]
        arg_sums = []
        steps = []
        for arg in eq_right.args:
            r = None
            for cl in cls:
                try:
                    r = cl(verbose=True).solver([simplify('a_(n)'), arg], f_num, l_num)
                    assert r.output[0].sympify()
                    arg_sums.extend(r.output[0].sympify())
                    break
                except Exception:
                    pass
            if not r:
                raise 'try fail'
        sn = sum(arg_sums)
        sn = simplify(sn)
        steps.append(["由分组求和法, 得", "%s的前%s项和为%s" % (new_latex(an[1]), new_latex(symbol), new_latex(sn))])
        self.output.append(BaseValues([sn]))
        self.steps.extend(steps)
        return self


class GetSums011(BaseFunction):
    """
    迭代求数列和
    """
    def solver(self, *args):
        an = args[0]
        num = args[1]
        num_symbols = num.free_symbols
        assert not num_symbols
        fn = (an[0] - an[1]).expand().simplify()
        fn = sl_new_an(fn)
        self.steps.append(["", "依题意，得"])
        self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs(fn)
        shulie_name = sl_shulie_name(fn)
        max_index, min_index = sl_max_min_index(fn)
        assert len(xiangs) == 1
        answer = solve(fn, shulie_name[0](min_index))
        eq_right = answer[0]
        min_xiang = shulie_name[0](n)
        sn = 0
        for i in range(1, num + 1):
            item = eq_right.subs({symbol: i})
            sn += item
        sn = expand(sn)
        sn = simplify(sn)
        if len(str(sn)) > 15:
            sn = MathematicaSimplify().solver(BasePoly(sn)).output[0].sympify()
        self.output.append(BaseValues([sn]))
        self.steps.append(["", "∴ %s的前%s项和为%s" % (new_latex(min_xiang), new_latex(num), new_latex(sn))])
        self.label.add("迭代法求数列和")
        return self


class GetSums012(BaseFunction):
    """
    求分段数列的和
    """
    def solver(self, *args):
        assert isinstance(args[0][1], BasePieceShuLie)
        cls = [GetSums001, GetSums002, GetSums003, GetSums004, GetSums005, GetSums006, GetSums007,
               GetSums007,
               GetSums010, GetSums011]
        an = args[0][1].sympify()
        num = args[1]
        n_sums = 0
        for ans in an[:-1]:
            ans_name, ans_value, ans_cond = ans
            ans_cond = list(ans_cond)
            ans_first_index = ans_cond[0]
            ans_first_r = None
            if len(ans_cond) == 1:
                n_sums = n_sums + ans_value.subs({sympify('n'): ans_first_index})
            else:
                for cl in cls:
                    try:
                        ans_first_r = cl(verbose=True).solver([ans_name, ans_value], ans_first_index - 1)
                        ans_first_r_values = ans_first_r.output[0].sympify()
                        for ans_first_r_value in ans_first_r_values:
                            n_sums = n_sums - ans_first_r_value
                        break
                    except Exception:
                        pass
                if not ans_first_r:
                    raise 'try fail'
                ans_final_index = ans_cond[-1]
                ans_final_r = None
                for cl in cls:
                    try:
                        ans_final_r = cl(verbose=True).solver([ans_name, ans_value], ans_final_index)
                        break
                    except Exception:
                        pass
                if not ans_final_r:
                    raise 'try fail'
                ans_final_r_values = ans_final_r.output[0].sympify()
                for ans_final_r_value in ans_final_r_values:
                    n_sums = n_sums + ans_final_r_value
        last_an_name, last_an_value, last_an_cond = an[-1]
        last_an_cond = list(last_an_cond)
        last_first_index = last_an_cond[0]
        last_first_r = None
        for cl in cls:
            try:
                last_first_r = cl(verbose=True).solver([last_an_name, last_an_value], last_first_index)
                break
            except Exception:
                pass
        if not last_first_r:
            raise 'try fail'
        last_first_r_values = last_first_r.output[0].sympify()
        for last_first_r_value in last_first_r_values:
            n_sums = n_sums - last_first_r_value + last_an_value.subs({sympify('n'): last_first_index})
        last_final_index = num
        last_final_r = None
        for cl in cls:
            try:
                last_final_r = cl(verbose=True).solver([last_an_name, last_an_value], last_final_index)
                break
            except Exception:
                pass
        if not last_final_r:
            raise 'try fail'
        last_final_r_values = last_final_r.output[0].sympify()
        for last_final_r_value in last_final_r_values:
            n_sums = n_sums + last_final_r_value
        n_sums = n_sums.expand().simplify()
        self.steps.append(["", "%s的前%s项和为：%s" % (new_latex(last_an_name), new_latex(num), new_latex(n_sums))])
        self.output.append(BaseValues([n_sums]))
        self.label.add("求分段数列的和-其他")
        return self


class GetSums013(BaseFunction):
    """
    1.分奇偶求和
    2.已知数列\\{a_{n}\\}满足a_{1}=1,a_{n+1}a_{n}=2^n,则S_{2016}=
    """
    def solver(self, *args):
        assert isinstance(args[0][1], BasePieceShuLie)
        an = args[0][1].sympify()
        assert len(an) == 2
        flag = []
        tong_xiang_name = None
        ji_shu_tong_xiang = None
        ou_shu_tong_xiang = None
        for ans in an:
            ans_name, ans_value, ans_cond = ans
            tong_xiang_name = ans_name
            if ans_cond == "n为奇数":
                ji_shu_tong_xiang = ans_value
            if ans_cond == "n为偶数":
                ou_shu_tong_xiang = ans_value
            if isinstance(ans_cond, str) and (ans_cond == "n为奇数" or ans_cond == "n为偶数"):
                flag.append(0)
            else:
                flag.append(1)
        assert sum(flag) == 0
        self.steps.append(["", "当n为奇数时"])
        new_ji_shu_tong_xiang1 = ji_shu_tong_xiang.subs({n: 2 * n + 1})
        new_ou_shu_tong_xiang1 = ou_shu_tong_xiang.subs({n: 2 * n})
        cls = [GetSums001, GetSums002, GetSums003, GetSums004, GetSums005, GetSums006, GetSums007,
               GetSums007,
               GetSums010, GetSums011]
        first_r1 = None
        for cl in cls:
            try:
                first_r1 = cl(verbose=True).solver([tong_xiang_name, new_ji_shu_tong_xiang1], n + 1)
                break
            except Exception:
                pass
        if not first_r1:
            raise 'try fail'
        assert first_r1
        self.steps += first_r1.steps
        self.label.update(first_r1.label)
        first_r_sums1 = first_r1.output[0].sympify()
        first_r2 = None
        for cl in cls:
            try:
                first_r2 = cl(verbose=True).solver([tong_xiang_name, new_ou_shu_tong_xiang1], n + 1)
                break
            except Exception:
                pass
        if not first_r2:
            raise 'try fail'
        assert first_r2
        self.steps += first_r2.steps
        self.label.update(first_r2.label)
        first_r_sums2 = first_r2.output[0].sympify()
        ji_shu_he = 0
        for item1, item2 in zip(first_r_sums1, first_r_sums2):
            ji_shu_he += item1 + item2
        ji_shu_he = ji_shu_he.subs({n: (n - 1) / 2})
        self.steps.append(["", "%s = %s" % (sympify('S_(n)'), new_latex(ji_shu_he))])
        self.steps.append(["", "当n为偶数时"])
        new_ji_shu_tong_xiang2 = ji_shu_tong_xiang.subs({n: 2 * n - 1})
        new_ou_shu_tong_xiang2 = ou_shu_tong_xiang.subs({n: 2 * n})
        second_r1 = None
        for cl in cls:
            try:
                second_r1 = cl(verbose=True).solver([tong_xiang_name, new_ji_shu_tong_xiang2], n)
                break
            except Exception:
                pass
        if not second_r1:
            raise 'try fail'
        assert second_r1
        self.steps += second_r1.steps
        self.label.update(second_r1.label)
        second_r_sums1 = second_r1.output[0].sympify()
        second_r2 = None
        for cl in cls:
            try:
                second_r2 = cl(verbose=True).solver([tong_xiang_name, new_ou_shu_tong_xiang2], n)
                break
            except Exception:
                pass
        if not second_r2:
            raise 'try fail'
        assert second_r2
        self.steps += second_r2.steps
        self.label.update(second_r2.label)
        second_r_sums2 = second_r2.output[0].sympify()
        ou_shu_he = 0
        for item1, item2 in zip(second_r_sums1, second_r_sums2):
            ou_shu_he += item1 + item2
        ou_shu_he = ou_shu_he.subs({n: n / 2})
        self.steps.append(["", "%s = %s" % (sympify('S_(n)'), new_latex(ou_shu_he))])
        new_sn = BasePieceShuLie({"var": n, "name": sympify('S_(n)'),
                                  "expression": [[ji_shu_he, "n为奇数"], [ou_shu_he, "n为偶数"]]})
        self.label.add("分段数列求和-奇偶型")
        self.output.append(new_sn)
        return self


# 求数列前n项和
class ShuLieQiuHe(BaseFunction):
    CLS = [GetSums001, GetSums002, GetSums003, GetSums004, GetSums005, GetSums006, GetSums007,
           GetSums008, GetSums010, GetSums011, GetSums012, GetSums013]

    def solver(self, *args):
        r = None
        for cl in ShuLieQiuHe.CLS:
            try:
                r = cl(verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r


if __name__ == '__main__':
    pass
